/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
 */

package org.apache.ranger.obs.security.token;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.obs.security.RangerAuthorizeProvider;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.token.Token;
import org.apache.hadoop.security.token.TokenInfo;
import org.apache.hadoop.security.token.TokenSelector;
import org.apache.ranger.obs.client.ClientConstants;
import org.apache.ranger.obs.protocolpb.RangerObsServiceProtocolPB;
import org.apache.ranger.obs.server.DistributedMiniServerBaseTest;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * description
 *
 * @since 2021-10-12
 */
public class DelegationTokenSelectorTest extends DistributedMiniServerBaseTest {

    private RangerAuthorizeProvider authorizer;

    private Configuration client_conf;

    @Before
    public void setUp() throws Exception {
        String principal = "ranger/hadoop@EXAMPLE.COM";
        authorizer = new RangerAuthorizeProvider();
        client_conf = new Configuration();
        client_conf.set("ranger.obs.service.rpc.address", "0.0.0.0:26901;0.0.0.0:26902");
        client_conf.set("ranger.obs.service.kerberos.principal", principal);
        authorizer.init(client_conf);
    }

    @After
    public void tearDown() {
    }

    @Test
    public void testSelectToken() throws IOException {
        Token<DelegationTokenIdentifier> token1 = (Token<DelegationTokenIdentifier>) authorizer.getDelegationToken(
            "yarn");
        Token<DelegationTokenIdentifier> token2 = (Token<DelegationTokenIdentifier>) authorizer.getDelegationToken(
            "ranger");
        List<Token<?>> tokens = new ArrayList<>();
        tokens.add(token1);
        tokens.add(token2);

        TokenInfo tokenInfo = SecurityUtil.getTokenInfo(RangerObsServiceProtocolPB.class, client_conf);
        TokenSelector<?> tokenSelector = null;
        try {
            tokenSelector = tokenInfo.value().newInstance();
        } catch (InstantiationException | IllegalAccessException e) {
            throw new IOException(e.toString(), e);
        }
        Token<DelegationTokenIdentifier> token = (Token<DelegationTokenIdentifier>) tokenSelector.selectToken(
            new Text(ClientConstants.DEFAULT_RANGER_OBS_SERVICE_DT_SERVICE_NAME),
            tokens);
        String renewer = DelegationTokenIdentifier.decodeDelegationToken(token).getRenewer().toString();
        Assert.assertEquals("testSelectToken", "yarn", renewer);
    }
}